<?php
use Util\LogUtil;
class WxPay
{
    CONST PAY_TYPE     = 'WX';
    CONST CODE         = 'WX';
    CONST PAY_FAILED   = 'PAY_FAILED';
    CONST CHECK_FAILED = 'CHECK_FAILED';
    CONST PAY_CLOSED   = 'PAY_CLOSED';
    public static function getPayConfig(){
        $resultTmp['pay_config'] = array(
            'APPID'=>'wx13b0ce87f8202ad4',
            'MCHID'=>'1246708301',
            'KEY'=>'d500ff67787dc9cc46c73907febcd424',
            'AppSecret'=>'734f4ea7dcccdd1c014907077de1df0d'
        );
        return $resultTmp;
    }
    public static function getPreSign($data,$orderItems,$outTradeNo,$open_id){
        if(empty($data)){
            throw new Exception('微信支付配置信息错误');
        }
        if(empty($orderItems)||empty($outTradeNo)){
            throw new Exception('获取订单或交易流水信息失败');
        }
        require_once dirname(dirname(__DIR__)).'/lib/WxPay/lib/WxPay.Api.php';
        $input = new WxPayUnifiedOrder();
        $input->SetAppid($data['pay_config']['APPID']);//设置公众号ID
        $input->SetMch_id($data['pay_config']['MCHID']);//商户号
        $input->SetBody('订单号:'.$orderItems['ordercode']);//设置商品或支付单简要描述
        $input->SetAttach($orderItems['id']);//设置附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
        $input->SetOut_trade_no($outTradeNo);//设置商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
        $input->SetTotal_fee($orderItems['need_pay_price']*100);//设置订单总金额，只能为整数，详见支付金额
        $input->SetTime_start(date('YmdHis',strtotime($orderItems['insert_time'])));//设置订单生成时间，格式为yyyyMMddHHmmss 20091225091010
        $input->SetTime_expire(date("YmdHis", time() + 600));//设置订单失效时间，格式为yyyyMMddHHmmss
        $input->SetGoods_tag('');//设置商品标记，代金券或立减优惠功能的参数，说明详见代金券或立减优惠
        $input->SetNotify_url('http://'.$_SERVER['HTTP_HOST'].'/WxPayCallback');//设置接收微信支付异步通知回调地址
        $input->SetTrade_type("JSAPI");//设置取值如下：JSAPI，NATIVE，APP，详细说明见参数规定
        $input->SetKey($data['pay_config']['KEY']);//商户私钥APIkey
        $input->SetOpenid($open_id);
        $order = WxPayApi::unifiedOrder($input);
        if($order){
            $datas = array(
                "appId"         => $order['appid'], //微信小写签名
                "timeStamp"     => (string) time(),
                "nonceStr"      => $order['nonce_str'],
                'package'       => 'prepay_id='.$order['prepay_id'],
                "signType"       => 'MD5',
            );
            // 195D7BA2FB58D9A00A15A7E86594CF22
            $datas['sign'] = self::makeSign($datas,$data['pay_config']['KEY']);
            return $datas;
        }
        throw new Exception('第二次签名失败');
    }

    /**
     * 计算签名demo
     * @param $data
     * @param $orderId
     * @return array
     * @throws Exception
     * @throws WxPayException
     */
    private static function makeSign($data,$key){
        //签名步骤一：按字典序排序参数
        ksort($data);
        /*---------------------------------*/
        $string = self::ToUrlParams($data);
        //签名步骤二：在string后加入KEY 04cc4ab7c18f13b2fd594b52dfdedfff
        $string = $string . "&key=".$key;

        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);

        return $result;
    }

    /**
     * 将数组转换成字符串
     * @param $data
     * @return string
     */
    private static function ToUrlParams($data)
    {
        $buff = "";
        foreach ($data as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }
/**
 * 查询微信支付订单
 * @param $oSutTradeNo
 * @param $enterpriseId
 * @return array
 * @throws Exception
 */
    public static function checkOrderQuery($data,$oSutTradeNo){
        if(empty($oSutTradeNo)){
            throw new Exception('微信支付配置信息错误');
        }

        require_once dirname(dirname(__DIR__)).'/lib/WxPay/lib/WxPay.Api.php';
        //查询微信支付订单
        $input = new WxPayOrderQuery();
        $input->SetAppid($data['pay_config']['APPID']);//'wx13b0ce87f8202ad4'
        $input->SetMch_id($data['pay_config']['MCHID']);//'1246708301'
        $input->SetKey($data['pay_config']['KEY']);//添加设置商户秘钥的方法  'd500ff67787dc9cc46c73907febcd424'
        $input->SetOut_trade_no($oSutTradeNo);// '5001000100020002771'
        $r = WxPayApi::orderQuery($input);
        $file = '/var/www/shanguang/a.txt';
        file_put_contents($file,json_encode($r)."-----checkOrderQuery----\n",FILE_APPEND);
        if($r){
            if($r["return_code"]=="SUCCESS"&&$r["result_code"]=="SUCCESS"&&($r["trade_state"]=="SUCCESS")) {
                return $r["transaction_id"];
            } else if ($r["result_code"]=="SUCCESS"
                &&($r["trade_state"]=="REVOKED"||$r["trade_state"]=="NOPAY"||$r["trade_state"]=="PAYERROR")) {
                return self::PAY_FAILED;
            }else if ($r["result_code"]=="SUCCESS"
                &&($r["trade_state"]=="REFUND"||$r['trade_state']=='USERPAYING')) {
                return self::PAY_FAILED;
            }else if ($r["result_code"]=="SUCCESS"
                &&($r["trade_state"]=="CLOSED")) {
                return self::PAY_CLOSED;
            }
            else {
                return self::CHECK_FAILED;
            }
        }
        return self::CHECK_FAILED;
    }
}